﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
// LitJson;
public class CreateSDF : MonoBehaviour
{

    //场景描述文件
    [Serializable]
    public class SDF
    {
        public ParamsData paramsObj;
        public List<ModelInfo> models;
        public SDF(List<ModelInfo> modelsP, ParamsData paramsObjP)
        {
            paramsObj = paramsObjP;
            models = modelsP;
        }
        public SDF()
        { }
    }


    [Serializable]
    public class SceneView
    {
        public string viewId;//视角ID
        public string viewName;//视角名称
        public float[] cameraParams = new float[] { 0, 0, 0, 0, -10f, 0, 0, 0, 0 };
        public SceneView()
        {

        }
    }
    [Serializable]
    public class KeyAnimation
    {
        public string animationIdentifier;
        public string animationName;
        public string modelName;
        public KeyAnimation(string modelNameP,string animationNameP)
        {
            modelName = modelNameP;
            animationIdentifier = modelName;
            animationName = animationNameP;
        }
    }
    [Serializable]
    public class ParamsData
    {
        public SceneView initView;
        public List<KeyAnimation> innerAnimations;
        public ParamsData()
        {
            initView = new SceneView();
            innerAnimations = new List<KeyAnimation>();
        }

    }
    [Serializable]
    public class ModelInfo
    {
        public string modelId;
        public string webLabel;
        public float[] spaceState = new float[9];
        public List<NodeInfo> subNodes;
    }
    [Serializable]
    public class NodeInfo
    {
        public string nodeId;
        public string webLabel;
        public List<NodeInfo> subNodes;
    }
    public static void ClearConsole()
    {
        //清空控制台Log信息--------------------------------------------------------------------------
        var logEntries = System.Type.GetType("UnityEditorInternal.LogEntries,UnityEditor.dll");
        var clearMethod = logEntries.GetMethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
        clearMethod.Invoke(null, null);
        //-------------------------------------------------------------------------------------------
    }
    public static void ExportSDFJsonDataWithRootPath(string path, string sceneName)
    {
        SDF sdf = null;
        GameObject[] goList = Selection.gameObjects;
        if (goList.Length < 1)
        {
            Debug.LogError("请先选择至少一个GameObject模型对象");
        }
        else
        {
            sdf = new SDF();
            sdf.paramsObj = new ParamsData();
            sdf.paramsObj.initView.viewId = "default";
            sdf.paramsObj.initView.viewName = "default";
            List<ModelInfo> data = new List<ModelInfo>();
            for (int i = 0; i < goList.Length; i++)
            {
                //遍历模型
                Transform currentGo = goList[i].transform;
                Animation animation = currentGo.GetComponent<Animation>();
                if (animation != null)
                {
                    Debug.Log("当前动画组件有动画:"+animation.GetClipCount());
                   AnimationClip[] aniList= AnimationUtility.GetAnimationClips(currentGo.gameObject);
                    for (int x = 0; x < aniList.Length; x++)
                    {
                        Debug.Log("动画片段名称:" + aniList[x].name);
                        sdf.paramsObj.innerAnimations.Add(new KeyAnimation(currentGo.name, aniList[x].name));
                    }
                }
                
                ModelInfo modelInfo = new ModelInfo();
                modelInfo.spaceState[0] = ConvertIntNumber(currentGo.transform.localPosition.x);
                modelInfo.spaceState[1] = ConvertIntNumber(currentGo.transform.localPosition.y);
                modelInfo.spaceState[2] = ConvertIntNumber(currentGo.transform.localPosition.z);

                modelInfo.spaceState[3] = ConvertIntNumber(currentGo.transform.eulerAngles.x);
                modelInfo.spaceState[4] = ConvertIntNumber(currentGo.transform.eulerAngles.y);
                modelInfo.spaceState[5] = ConvertIntNumber(currentGo.transform.eulerAngles.z);

                modelInfo.spaceState[6] = ConvertIntNumber(currentGo.transform.localScale.x);
                modelInfo.spaceState[7] = ConvertIntNumber(currentGo.transform.localScale.y);
                modelInfo.spaceState[8] = ConvertIntNumber(currentGo.transform.localScale.z);

                modelInfo.modelId = currentGo.name;
                modelInfo.webLabel = currentGo.name;
                Debug.Log("添加场景模型:" + goList[i].name);
                modelInfo.subNodes = new List<NodeInfo>();
                NodeInfo root = new NodeInfo();
                root.nodeId = currentGo.name;
                root.webLabel = currentGo.name;
                root.subNodes = new List<NodeInfo>();
                modelInfo.subNodes.Add(root);
                Dictionary<string, int> nodeDic = new Dictionary<string, int>();
                for (int m = 0; m < currentGo.childCount; m++)
                {
                    string nodeName = currentGo.GetChild(m).name;
                    if (nodeDic.ContainsKey(nodeName))
                    {
                        nodeDic[nodeName] = nodeDic[nodeName] + 1;
                        currentGo.GetChild(m).name = currentGo.GetChild(m).name + "_" + nodeDic[nodeName];
                        Debug.LogFormat("{0}的子节点中，出现重复的节点,添加角标后的名字为:{1}", currentGo.name, currentGo.GetChild(m).name);
                    }
                    else
                    {
                        nodeDic.Add(nodeName, 0);
                    }
                }
                for (int m = 0; m < currentGo.childCount; m++)
                {
                    //遍历第一层级
                    NodeInfo ni = new NodeInfo();
                    ni.nodeId = currentGo.GetChild(m).name;
                    ni.webLabel = ni.nodeId;
                    Transform curGo = currentGo.GetChild(m);
                    ni.subNodes = new List<NodeInfo>();
                    Dictionary<string, int> nodeDicTwo = new Dictionary<string, int>();
                    for (int k = 0; k < curGo.childCount; k++)
                    {
                        string nodeName = curGo.GetChild(k).name;
                        if (nodeDicTwo.ContainsKey(nodeName))
                        {
                            nodeDicTwo[nodeName] = nodeDicTwo[nodeName] + 1;
                            curGo.GetChild(k).name = curGo.GetChild(k).name + "_" + nodeDicTwo[nodeName];
                            Debug.LogFormat("{0}的子节点中，出现重复的节点,添加角标后的名字为:{1}", curGo.name, curGo.GetChild(k).name);
                        }
                        else
                        {
                            nodeDicTwo.Add(nodeName, 0);
                        }
                    }
                    for (int n = 0; n < curGo.childCount; n++)
                    {
                        //遍历第二层级
                        NodeInfo subNode = new NodeInfo();
                        subNode.nodeId = curGo.GetChild(n).name;
                        subNode.webLabel = subNode.nodeId;
                        ni.subNodes.Add(subNode);
                    }
                    modelInfo.subNodes[0].subNodes.Add(ni);
                }

                data.Add(modelInfo);
                UpdatePrefab(currentGo.gameObject);
            }
            sdf.models = data;

            string allModelJsonData = JsonUtility.ToJson(sdf);
            allModelJsonData = allModelJsonData.Replace("paramsObj", "params");
            Debug.Log("导出场景SDF文件:" + allModelJsonData);
            string fileName = path + "/" + sceneName + ".sdf";
            FileStream aFile = new FileStream(fileName, FileMode.Create);
            StreamWriter sw = new StreamWriter(aFile);
            sw.Write(allModelJsonData);
            sw.Close();
            sw.Dispose();
            Debug.Log(fileName + "场景SDF文件创建完毕！");
            AssetDatabase.Refresh();
        }
    }
    static float ConvertIntNumber(float oldVal, int number = 4)
    {
        int divisor = (int)Mathf.Pow(10, number);
        float val = Mathf.Round(oldVal * divisor) / divisor;
        //Debug.Log("转换后:" + val);
        //通过UnityJson转换后float的值会改变，这里序列化后面会换个其它的库
        return oldVal;
    }
    //[MenuItem("CreateSDF/Export")]
    static void ExportSDFJsonData()
    {
        ClearConsole();
        string assetBundlesRootName = "AssetBundles";
        string assetBundlesRootPath = Application.dataPath + "/" + assetBundlesRootName;
        string androidRootPath = assetBundlesRootPath + "/Android";
        string winRootPath = assetBundlesRootPath + "/Win";
        string iosRootPath = assetBundlesRootPath + "/IOS";
        string hololensRootPath = assetBundlesRootPath + "/Hololens";
        string sdfRootPath = assetBundlesRootPath + "/SDF";
        if (!Directory.Exists(assetBundlesRootPath))
        {
            Debug.Log("项目中没有需要的文件夹，直接创建" + assetBundlesRootPath);
            AssetDatabase.CreateFolder("Assets", assetBundlesRootName);
        }
        if (!Directory.Exists(androidRootPath))
        {
            AssetDatabase.CreateFolder("Assets/" + assetBundlesRootName, "Android");
        }
        if (!Directory.Exists(winRootPath))
        {
            AssetDatabase.CreateFolder("Assets/" + assetBundlesRootName, "Win");
        }
        if (!Directory.Exists(iosRootPath))
        {
            AssetDatabase.CreateFolder("Assets/" + assetBundlesRootName, "IOS");
        }
        if (!Directory.Exists(hololensRootPath))
        {
            AssetDatabase.CreateFolder("Assets/" + assetBundlesRootName, "Hololens");
        }
        if (!Directory.Exists(sdfRootPath))
        {
            AssetDatabase.CreateFolder("Assets/" + assetBundlesRootName, "SDF");
        }

        SDF sdf = null;
        GameObject[] goList = Selection.gameObjects;
        if (goList.Length < 1)
        {
            Debug.LogError("请先选择至少一个GameObject模型对象");
        }
        else
        {
            sdf = new SDF();
            sdf.paramsObj = new ParamsData();
            List<ModelInfo> data = new List<ModelInfo>();

            for (int i = 0; i < goList.Length; i++)
            {
                //遍历模型
                Transform currentGo = goList[i].transform;
                ModelInfo modelInfo = new ModelInfo();
                modelInfo.modelId = currentGo.name;
                modelInfo.webLabel = currentGo.name;
                Debug.Log("添加场景模型:" + goList[i].name);
                modelInfo.subNodes = new List<NodeInfo>();
                Dictionary<string, int> nodeDic = new Dictionary<string, int>();
                for (int m = 0; m < currentGo.childCount; m++)
                {
                    string nodeName = currentGo.GetChild(m).name;
                    if (nodeDic.ContainsKey(nodeName))
                    {
                        nodeDic[nodeName] = nodeDic[nodeName] + 1;
                        currentGo.GetChild(m).name = currentGo.GetChild(m).name + "_" + nodeDic[nodeName];
                        Debug.LogFormat("{0}的子节点中，出现重复的节点,添加角标后的名字为:{1}", currentGo.name, currentGo.GetChild(m).name);
                    }
                    else
                    {
                        nodeDic.Add(nodeName, 0);
                    }
                }
                for (int m = 0; m < currentGo.childCount; m++)
                {
                    //遍历第一层级
                    NodeInfo ni = new NodeInfo();
                    ni.nodeId = currentGo.GetChild(m).name;
                    ni.webLabel = ni.nodeId;
                    Transform curGo = currentGo.GetChild(m);
                    ni.subNodes = new List<NodeInfo>();
                    Dictionary<string, int> nodeDicTwo = new Dictionary<string, int>();
                    for (int k = 0; k < curGo.childCount; k++)
                    {
                        string nodeName = curGo.GetChild(k).name;
                        if (nodeDicTwo.ContainsKey(nodeName))
                        {
                            nodeDicTwo[nodeName] = nodeDicTwo[nodeName] + 1;
                            curGo.GetChild(k).name = curGo.GetChild(k).name + "_" + nodeDicTwo[nodeName];
                            Debug.LogFormat("{0}的子节点中，出现重复的节点,添加角标后的名字为:{1}", curGo.name, curGo.GetChild(k).name);
                        }
                        else
                        {
                            nodeDicTwo.Add(nodeName, 0);
                        }
                    }
                    for (int n = 0; n < curGo.childCount; n++)
                    {
                        //遍历第二层级
                        NodeInfo subNode = new NodeInfo();
                        subNode.nodeId = curGo.GetChild(n).name;
                        subNode.webLabel = subNode.nodeId;
                        ni.subNodes.Add(subNode);
                    }
                    modelInfo.subNodes.Add(ni);
                }

                data.Add(modelInfo);
                UpdatePrefab(currentGo.gameObject);
            }
            sdf.models = data;

            string allModelJsonData = JsonUtility.ToJson(sdf);
            allModelJsonData = allModelJsonData.Replace("paramsObj", "params");
            Debug.Log("导出场景SDF文件:" + allModelJsonData);
            string fileName = sdfRootPath + "/" + goList[0].name + ".sdf";
            FileStream aFile = new FileStream(fileName, FileMode.Create);
            StreamWriter sw = new StreamWriter(aFile);
            sw.Write(allModelJsonData);
            sw.Close();
            sw.Dispose();
            Debug.Log(fileName + "场景SDF文件创建完毕！");
            AssetDatabase.Refresh();
        }
    }
    static void UpdatePrefab(GameObject go)
    {
        //判断选择的物体，是否为预设  
        if (PrefabUtility.GetPrefabType(go) == PrefabType.PrefabInstance)
        {
            UnityEngine.Object parentObject = PrefabUtility.GetPrefabParent(go);
            //替换预设  
            PrefabUtility.ReplacePrefab(go, parentObject, ReplacePrefabOptions.ConnectToPrefab);
            Debug.Log("解决子节点重名问题后，更新预设");
            //刷新  
            AssetDatabase.Refresh();
        }
    }
}